﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

using ECCIT.IO;

namespace ECCIT.Report.Excel
{
    public class HtmlTemplate
    {
        private HtmlTemplateCell _html;
        private HtmlTemplateCell _head;
        private HtmlTemplateCell _body;
        private HtmlTemplateCell _table;
        private string _colGroup;
        private List<HtmlTemplateRow> _rows;
        private HtmlTemplateRow _sumRow;

        public HtmlTemplateCell Html
        {
            get { return _html; }
            set { _html = value; }
        }

        public HtmlTemplateCell Head
        {
            get { return _head; }
            set { _head = value; }
        }

        public HtmlTemplateCell Body
        {
            get { return _body; }
            set { _body = value; }
        }

        public HtmlTemplateCell Table
        {
            get { return _table; }
            set { _table = value; }
        }

        public string ColGroup
        {
            get { return _colGroup; }
            set { _colGroup = value; }
        }

        public List<HtmlTemplateRow> Rows
        {
            get { return _rows; }
            set { _rows = value; }
        }

        public HtmlTemplateRow SumRow
        {
            get { return _sumRow; }
            set { _sumRow = value; }
        }

        public HtmlTemplate()
        {
            //
            //TODO: 在此处添加构造函数逻辑
            //
        }

        private static string GetExcelContent(DataItemPath excelFilePath, Encoding encoding)
        {
            string filePath = excelFilePath.PhysicalPath;
            if (!File.Exists(filePath))
                throw new FileNotFoundException(string.Format("File: {0} does not exist.", filePath));

            string content = File.ReadAllText(filePath, encoding);
            return content;
        }

        private static string GetStartTag(string content, string tagName)
        {
            string commonTag = string.Format("<{0}>", tagName);
            if (content.Trim() == string.Empty)
                return commonTag;

            int startIndex = content.IndexOf("<" + tagName, 0);
            if (startIndex == -1)
                return commonTag;

            int endIndex = content.IndexOf(">", startIndex);
            if (endIndex == -1)
                return commonTag;

            string startTag = content.Substring(startIndex, endIndex - startIndex + 1);
            return startTag;
        }

        private static string GetTagContent(string content, string tagName)
        {
            string startTag = GetStartTag(content, tagName);
            int startIndex = content.IndexOf(startTag);
            if (startIndex == -1)
                return string.Empty;

            int endIndex = content.IndexOf(string.Format("</{0}>", tagName), startIndex);
            if (endIndex == -1)
                return string.Empty;

            string tagContent = content.Substring(startIndex + startTag.Length, endIndex - startIndex - startTag.Length);
            return tagContent;
        }

        private static string GetHtmlStartTag(string content)
        {
            string startTag = GetStartTag(content, "html");
            return startTag;
        }

        private static string GetHeadStartTag(string content)
        {
            string commonTag = "<head>";
            int startIndex = content.IndexOf("<head");
            if (startIndex == -1)
                return commonTag;

            int endIndex = content.IndexOf("</head>", startIndex);
            if (endIndex == -1)
                return commonTag;

            string startTag = content.Substring(startIndex, endIndex - startIndex);
            return startTag;
        }

        private static string GetBodyStartTag(string content)
        {
            string startTag = GetStartTag(content, "body");
            return startTag;
        }

        private static string GetColGroup(string content)
        {
            int colStartIndex = content.IndexOf("<col", 0);
            int colEndIndex = content.IndexOf("<tr", colStartIndex);
            if (colEndIndex == -1)
                colEndIndex = content.IndexOf("</table>", colStartIndex);

            string colGroup = string.Empty;
            if (colStartIndex > -1 && colEndIndex > -1)
                colGroup = content.Substring(colStartIndex, colEndIndex - colStartIndex);

            return colGroup;
        }

        private static List<HtmlTemplateCell> GetCells(string content)
        {
            int startIndex = -1;
            int endIndex = -1;
            string cellStart = string.Empty;
            string cellEnd = "</td>";
            string cellHtml = string.Empty;
            string cellContent = string.Empty;
            HtmlTemplateCell cell = null;
            List<HtmlTemplateCell> cells = new List<HtmlTemplateCell>();
            while ((startIndex = content.IndexOf("<td")) > -1)
            {
                endIndex = content.IndexOf(cellEnd, startIndex);
                if (endIndex == -1)
                    break;

                cellHtml = content.Substring(startIndex, endIndex - startIndex + cellEnd.Length);
                cellStart = GetStartTag(cellHtml, "td");
                cellContent = GetTagContent(cellHtml, "td");
                cell = new HtmlTemplateCell(cellStart, cellEnd);
                cell.InnerText = cellContent;

                cells.Add(cell);
                content = content.Substring(endIndex + cellEnd.Length);
            }

            return cells;
        }

        public static List<HtmlTemplateRow> GetRows(string content)
        {
            List<HtmlTemplateRow> rows = new List<HtmlTemplateRow>();
            int startIndex = -1;
            int endIndex = -1;
            string rowHtml = string.Empty;
            string rowStart = string.Empty;
            string rowEnd = "</tr>";
            int index = 0;
            while ((startIndex = content.IndexOf("<tr")) > -1)
            {
                endIndex = content.IndexOf(rowEnd, startIndex);
                if (endIndex == -1)
                    break;

                rowHtml = content.Substring(startIndex, endIndex - startIndex + rowEnd.Length);
                rowStart = GetStartTag(rowHtml, "tr");
                HtmlTemplateRow row = new HtmlTemplateRow(index, rowStart, rowEnd);
                row.Cells = GetCells(GetTagContent(rowHtml, "tr"));
                content = content.Substring(endIndex + rowEnd.Length);

                rows.Add(row);
                index++;
            }

            return rows;
        }

        public static HtmlTemplate CreateInstance(DataItemPath appPath, Encoding encoding)
        {
            string excelContent = GetExcelContent(appPath, encoding);
            return CreateInstance(excelContent);
        }

        public static HtmlTemplate CreateInstance(string excelContent)
        {
            // get html tag
            string htmlStart = GetHtmlStartTag(excelContent);
            string htmlEnd = "</html>";
            HtmlTemplateCell html = new HtmlTemplateCell(htmlStart, htmlEnd);

            // get head tag
            //string headStart = GetHeadStartTag(excelContent);
            string headStart = GetStartTag(excelContent, "head");
            string headEnd = "</head>";
            HtmlTemplateCell head = new HtmlTemplateCell(headStart, headEnd);
            head.InnerText = GetTagContent(excelContent, "head");

            // get body tag
            string bodyStart = GetBodyStartTag(excelContent);
            string bodyEnd = "</body>";
            HtmlTemplateCell body = new HtmlTemplateCell(bodyStart, bodyEnd);

            // get table tag
            string tableStart = GetStartTag(excelContent, "table");
            string tableEnd = "</table>";
            HtmlTemplateCell table = new HtmlTemplateCell(tableStart, tableEnd);

            // get col group
            string colGroup = GetColGroup(excelContent);

            // get rows
            List<HtmlTemplateRow> rows = GetRows(excelContent);

            HtmlTemplate template = new HtmlTemplate();
            template.Html = html;
            template.Head = head;
            template.Body = body;
            template.Table = table;
            template.ColGroup = colGroup;
            template.Rows = rows;
            return template;
        }

        public override string ToString()
        {
            StringBuilder builder = new StringBuilder();
            builder.Append(_html.Start).Append(Environment.NewLine);
            builder.Append(_head.ToString()).Append(Environment.NewLine);
            builder.Append(_body.Start).Append(Environment.NewLine);
            builder.Append(_table.Start).Append(Environment.NewLine);
            builder.Append(_colGroup).Append(Environment.NewLine);
            foreach (HtmlTemplateRow row in _rows)
            {
                builder.Append(row.ToString()).Append(Environment.NewLine);
            }
            builder.Append(_table.End).Append(Environment.NewLine);
            builder.Append(_body.End).Append(Environment.NewLine);
            builder.Append(_html.End).Append(Environment.NewLine);

            return builder.ToString();
        }
    }
}
